package com.atguigu.mq.config;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
/**
 * MQProducerAckConfig类实现了RabbitTemplate的ConfirmCallback和ReturnsCallback接口
 * 它主要用于处理消息发送到RabbitMQ后的确认和返回逻辑
 */
public class MQProducerAckConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnsCallback {


    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnsCallback(this);
    }

    /**
     * 确认消息发送的回调方法
     * 当消息发送到RabbitMQ并被确认时，此方法将被调用
     *
     * @param correlationData 相关数据，用于标识和关联消息
     * @param ack 消息是否被成功确认的标志
     * @param cause 如果消息未被确认，提供失败的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) { // 确认模式
        if (ack) {
            log.info("消息发送成功 数据: " + correlationData);
        } else {
            log.error("消息发送失败 数据: " + correlationData + "/n错误信息: " + cause);
        }
    }

    /**
     * 处理回退消息的方法
     * 当消息无法被正确处理时，此方法将被调用，以处理回退模式下的消息
     *
     * @param returned 回退的消息对象，包含有关消息回退的信息
     */
    @Override
    public void returnedMessage(ReturnedMessage returned) { // 回退模式
        log.info("消息主体: " + new String(returned.getMessage().getBody()));
        log.info("应答码: " + returned.getReplyCode());
        log.info("描述：" + returned.getReplyText());
        log.info("消息使用的交换器 exchange : " + returned.getExchange());
        log.info("消息使用的路由键 routing : " + returned.getRoutingKey());
    }
}
